/**
 * 
 */
package org.softTank.wsdlParser;

import java.io.File;
import java.net.URL;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
import org.dom4j.io.SAXReader;

/**
 * @author Yuzone
 * 
 */
public class BpelDecoratorImpl implements BpelDecorator {

	protected Logger logger;

	public BpelDecoratorImpl() {
		PropertyConfigurator.configure("main/resource/log4j.properties");
		logger = Logger.getLogger(this.getClass());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.softTank.wsdlParser.BpelDecorator#decorateWSDL(java.net.URL)
	 */
	@Override
	public String decorateWSDL(URL url) {
		SAXReader reader = new SAXReader();
		try {
			Document doc = reader.read(url);
			return decorate(doc);
		} catch (DocumentException e) {
			logger.error("Cannot read WSDL from the given url!"
					+ e.getMessage());
		}

		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.softTank.wsdlParser.BpelDecorator#decorateWSDL(java.io.File)
	 */
	@Override
	public String decorateWSDL(File file) {
		SAXReader reader = new SAXReader();
		try {
			Document doc = reader.read(file);
			return decorate(doc);
		} catch (DocumentException e) {
			logger.error("Cannot read WSDL from the given file!"
					+ e.getMessage());
		}

		return null;
	}

	@SuppressWarnings("unchecked")
	protected String decorate(Document doc) {
		Element root = doc.getRootElement();
		// Document object won't be null even if WSDL source is null.
		// If source is null, then root element is the default one: <html/>
		if (root.getName().equals("html"))
			return null;
		// Element portType = root.element("portType");
		List<Element> portTypes = root.elements("portType");
		if (portTypes == null) {
			logger.debug("No portType definition in this WSDL!");
			return root.asXML();
		}

		logger.debug("Start to edit WSDL...");
		// Add namespace to WSDL
		Namespace ns = new Namespace("plnk",
				"http://docs.oasis-open.org/wsbpel/2.0/plnktype");
		root.add(ns);

		for (Element portType : portTypes) {
			// Create partnerLinkType element to WSDL
			Element partnerLinkType = DocumentHelper.createElement(new QName(
					"partnerLinkType", ns));
			partnerLinkType.addAttribute("name", "plt"
					+ portType.attributeValue("name"));
			partnerLinkType.addNamespace("tns0", root
					.attributeValue("targetNamespace"));
			// Add role element to partnerLinkType element
			Element role = DocumentHelper.createElement(new QName("role", ns));
			role.addAttribute("name", "role" + portType.attributeValue("name"));
			role.addAttribute("portType", "tns0:"
					+ portType.attributeValue("name"));
			partnerLinkType.add(role);
			// Add partnerLinkType element to WSDL
			root.add(partnerLinkType);
		}

		logger.debug("Edit WSDL successfully!");
		return doc.asXML();
	}
}
